#ifndef __M_ROUTER_H__
#define __M_ROUTER_H__
#include <iostream>
#include "../mqcommon/mq_helper.hpp"
#include "../mqcommon/mq_logger.hpp"
#include "../mqcommon/mq_msg.pb.h"
// 交换路由模块
namespace bitmq
{
    class Router
    {
    public:
        // 判断routing_key是否合法
        static bool isLegalRouting_Key(const std::string &routing_key)
        {
            // 判断是否有非法字符  合法字符:  a~z   A~z  0~9  .  _
            for (auto &ch : routing_key)
            {
                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9') ||
                    ch == '.' || ch == '_')
                {
                    continue;
                }
                return false;
            }
            return true;
        }
        // 判断binding_key是否合法
        static bool isLEgalBinding_Key(const std::string &binding_key)
        {
            //1、判断是否有非法字符  合法字符:  a~z   A~z  0~9  .  _ * #
            for (auto &ch : binding_key)
            {
                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9') ||
                    ch == '.' || ch == '_'||ch=='*'||ch=='#')
                {
                    continue;
                }
                return false;
            }
            //2、判断通配符是否独立存在
            std::vector<std::string> words;
            StrHelper::split(binding_key,".",words);
            for(auto&word:words)
            {
                //在每个单词里找是否有通配符且单词个数大于一
                if(((word.size()>1&&word.find('*')!=std::string::npos)||(word.size()>1&&word.find('#')!=std::string::npos)))
                {
                    return false;
                }
            }
            //3、#两边单词不能有其他通配符
            for(int i=1;i<words.size();i++)
            {
                if(words[i]=="*"&&words[i-1]=="#")
                return false;
                if(words[i]=="#"&&words[i-1]=="#")
                return false;
                if(words[i]=="#"&&words[i-1]=="*")
                return false;
            }

            return true;
        }
        // 进行路由选择
        static bool route(ExchageType type, const std::string &routing_key, const std::string &binding_key)
        {
            //直接路由
            if(type==ExchageType::DERICT)
            {
                return (routing_key==binding_key);
            }
            //广播路由
            else if(type==ExchageType::FANOUT)
            {
                return true;
            }
            //主题路由
            //1、将routing_key和binding_key的单词切割进数组
            std::vector<std::string> bkey;
            std::vector<std::string> rkey; 
            int n_bkey=StrHelper::split(binding_key,".",bkey);
            int n_rkey=StrHelper::split(routing_key,".",rkey);
            //2、定义标记数组，并将[0][0]位置标志位 true 其他位置标志为  false
            std::vector<std::vector<bool>> dp(n_bkey+1,std::vector<bool>(n_rkey+1,false));
            dp[0][0]=true;
            //3、如果binding_key起始位置为# ，将[1][0]置为true
            if(bkey[0]=="#")
            {
                dp[1][0]=true;
            }
            // for(int i=1;i<n_bkey;i++)
            // {
            //     if(bkey[i-1]=="#")
            //     {
            //         dp[i][0]=true;
            //         continue;
            //     }
            //     break;
            // }
            //4、进行routing_key和binding_key匹配置位

            for(int i=1;i<=n_bkey;i++)
            {
                for(int j=1;j<=n_rkey;j++)
                {
                    //两个单词匹配时，或者"*"与单词匹配时  标志位从左上角继承
                    if(bkey[i-1]==rkey[j-1]||bkey[i-1]=="*")
                    {
                        dp[i][j]=dp[i-1][j-1];
                    }
                    else if(bkey[i-1]=="#")//"#"与单词匹配时，从上 左  左上角继承
                    {
                        dp[i][j]=dp[i-1][j-1]|dp[i][j-1]|dp[i-1][j];
                    }
                }
            }

            return dp[n_bkey][n_rkey];
        }
    };
}
#endif